<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
      <el-form-item label="角色名称" prop="name">
        <el-input v-model="queryParams.name" placeholder="请输入角色名称" clearable size="small" style="width: 240px"
          @keyup.enter.native="handleQuery" />
      </el-form-item>

      <el-form-item>
        <el-button v-preventReClick type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button v-preventReClick icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button v-preventReClick type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['system:role:create']">新建角色</el-button>
      </el-col>
    </el-row>

    <el-table v-loading="loading" :data="roleList" class="margin-top">
      <el-table-column label="角色名称" prop="name" :show-overflow-tooltip="true" />
      <el-table-column label="角色编码" prop="code" />
      <el-table-column label="创建人" prop="processor" />
      <el-table-column label="创建时间" align="center" prop="processTime" :formatter="$util.YYMM" />
      <el-table-column label="状态" prop="status" align="center" >
        <template v-slot="scope">
          <div v-if="scope.row.status == 0">已启用</div>
          <div v-if="scope.row.status == 1">已禁用</div>
        </template>
      </el-table-column>

      <el-table-column label="操作" align="center" fixed="right" width="200" class-name="small-padding fixed-width">
        <template v-slot="scope">
          <div v-if="scope.row.type == 1">
            <el-button v-preventReClick size="mini" type="text" @click="handleView(scope.row)">查看</el-button>
            <span class="spans">|</span>
            <el-button v-preventReClick size="mini" type="text" @click="handleGrant(scope.row)"
              v-hasPermi="['system:role:delete']">对象授权</el-button>
          </div>
          <div v-else>
            <el-button v-preventReClick size="mini" type="text" @click="handleView(scope.row)">查看</el-button>
            <span class="spans">|</span>
            <el-button v-preventReClick size="mini" type="text" v-if="scope.row.status == 1"
              @click="handleEditStatus(scope.row, 0, '启用')">启用</el-button>
            <el-button v-preventReClick size="mini" type="text" v-if="scope.row.status == 0"
              @click="handleEditStatus(scope.row, 1, '禁用')">禁用</el-button>
            <span class="spans">|</span>
            <el-button v-preventReClick size="mini" type="text" v-if="scope.row.status == 0"
              @click="handleGrant(scope.row)">对象授权</el-button>
            <el-button v-preventReClick size="mini" type="text" v-if="scope.row.status == 1"
              :disabled="scope.row.status == 0" @click="handleUpdate(scope.row)">编辑</el-button>
            <span class="spans" v-if="scope.row.status == 1">|</span>
            <el-dropdown v-if="scope.row.status == 1" :disabled="scope.row.status == 0">
              <el-button v-preventReClick type="text">
                更多<i class="el-icon-arrow-down el-icon--right"></i>
              </el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>
                  <el-button v-preventReClick size="mini" type="text" @click="handleDataScope(scope.row)"
                    v-hasPermi="['system:role:delete']">功能授权</el-button>
                </el-dropdown-item>
                <el-dropdown-item>
                  <el-button v-preventReClick size="mini" type="text" @click="handleGrant(scope.row)"
                    v-hasPermi="['system:role:delete']">对象授权</el-button>
                </el-dropdown-item>
                <el-dropdown-item>
                  <el-button v-preventReClick size="mini" type="text" @click="handleDelete(scope.row)">删除</el-button>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改角色配置对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="700px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="90px">
        <el-row class="margin-top">
          <el-col :span="12">
            <el-form-item label="角色名称" prop="name">
              <el-input v-model.trim="form.name" placeholder="请输入角色名称" @input="handlegenCode" :verify="verifyName" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色编码" prop="code">
              <el-input v-model="form.code" disabled placeholder="自动生成" />
            </el-form-item>
          </el-col>

          <el-col :span="24" class="margin-top">
            <el-form-item label="备注">
              <el-input type="textarea" :autosize="{ minRows: 3, maxRows: 5 }" :rows="3" placeholder="请输入内容"
                show-word-limit resize="none" maxlength="100" v-model="form.remark">
              </el-input>
            </el-form-item>
          </el-col>


        </el-row>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-preventReClick type="primary" @click="submitForm">确 定</el-button>
        <el-button v-preventReClick @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 分配角色的数据权限对话框 -->
    <el-dialog title="分配数据权限" :visible.sync="openDataScope" width="500px" append-to-body>
      <el-form :model="form" label-width="80px">
        <el-form-item label="角色名称">
          <el-input v-model="form.name" :disabled="true" />
        </el-form-item>
        <el-form-item label="角色标识">
          <el-input v-model="form.code" :disabled="true" />
        </el-form-item>
        <el-form-item label="权限范围">
          <el-select v-model="form.dataScope">
            <el-option v-for="item in dataScopeDictDatas" :key="parseInt(item.value)" :label="item.label"
              :value="parseInt(item.value)"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据权限" v-show="form.dataScope === SysDataScopeEnum.DEPT_CUSTOM">
          <el-checkbox :checked="!form.deptCheckStrictly"
            @change="handleCheckedTreeConnect($event, 'dept')">父子联动(选中父节点，自动选择子节点)</el-checkbox>
          <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
          <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
          <el-tree class="tree-border" :data="deptOptions" show-checkbox default-expand-all ref="dept" node-key="id"
            :check-strictly="form.deptCheckStrictly" empty-text="加载中，请稍后" :props="defaultProps"></el-tree>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-preventReClick type="primary" @click="submitDataScope">确 定</el-button>
        <el-button v-preventReClick @click="cancelDataScope">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 分配角色的菜单权限对话框 -->
    <el-dialog :title="title" :visible.sync="openMenu" width="500px" append-to-body>
      <el-form :model="form" label-width="80px">
        <el-form-item label="角色名称">
          <el-input v-model="form.name" :disabled="true" />
        </el-form-item>
        <el-form-item label="角色标识">
          <el-input v-model="form.code" :disabled="true" />
        </el-form-item>
        <el-form-item label="菜单权限">
          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
          <el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menu" node-key="id"
            :check-strictly="form.menuCheckStrictly" empty-text="加载中，请稍后" :props="defaultProps"></el-tree>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-preventReClick type="primary" @click="submitMenu">确 定</el-button>
        <el-button v-preventReClick @click="cancelMenu">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 对象授权组件 -->
    <usergrantDialog ref="usergrantDialog" title="对象授权" @emitplayer="emitplayer"></usergrantDialog>

    <!-- 查看组件 -->
    <ViewDialog ref="ViewDialog"></ViewDialog>
  </div>
</template>

<script>
import {
  changeRoleStatus,
  exportRole,

} from "@/api/system/role";
import { roleUsersAndGroups, updateRoleUsersAndGroups } from "@/api/system/userGroup"

import {
  listRole, createRole, getRole, assignRoleUsers, listRoleUsers,
  updateRoleStatus, updateRole, delRole, roleConfig, genCode
} from "@/api/common/role";

import { listSimpleMenus } from "@/api/system/menu";
import { assignRoleMenu, listRoleMenus, assignRoleDataScope } from "@/api/system/permission";
import { listSimpleDepts } from "@/api/system/dept";
import { CommonStatusEnum, SystemDataScopeEnum } from "@/utils/constants";
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
import usergrantDialog from "@/components/common/usergrantDialog/index.vue"
import ViewDialog from "./components/view.vue"


export default {
  components: {
    usergrantDialog, ViewDialog
  },
  name: "SystemRole",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 导出遮罩层
      exportLoading: false,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 角色表格数据
      roleList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 是否显示弹出层（数据权限）
      openDataScope: false,
      // 是否显示弹出层（菜单权限）
      openMenu: false,
      menuExpand: false,
      menuNodeAll: false,
      deptExpand: true,
      deptNodeAll: false,
      // 菜单列表
      menuOptions: [],
      // 部门列表
      deptOptions: [], // 部门属性结构
      depts: [], // 部门列表
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 10,
        type: 1,
        name: undefined,
        code: undefined
      },
      // 表单参数
      form: {},
      //当前选择的用户:授权操作
      currow: null,
      defaultProps: {
        label: "name",
        children: "children"
      },
      // 表单校验
      rules: {
        name: [
          { required: true, message: "角色名称不能为空", trigger: "blur" }
        ],
        code: [
          { required: true, message: "角色标识不能为空", trigger: "blur" }
        ],
        sort: [
          { required: true, message: "角色顺序不能为空", trigger: "blur" }
        ]
      },

      // 枚举
      SysCommonStatusEnum: CommonStatusEnum,
      SysDataScopeEnum: SystemDataScopeEnum,
      // 数据字典
      roleTypeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_ROLE_TYPE),
      statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS),
      dataScopeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_DATA_SCOPE)
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询角色列表 */
    getList() {
      this.loading = true;
      listRole(this.queryParams).then(
        response => {
          this.roleList = response.data.list;
          this.total = response.data.total;
          this.loading = false;
        }
      ).catch(err => this.loading = false)
    },
    /**查看详情 */
    handleView(row) {
      const { id } = row
      this.$refs.ViewDialog.init(id)
    },
    //生成编码
    handlegenCode() {
      const data = {
        name: this.form.name,
        type: 1,
        label: 2
      }
      genCode(data).then(res => {
        if (!res.data.nameCode) return this.$message.error('生成失败')

        this.$set(this.form, 'code', res.data.nameCode)
      })
    },
    /**对象授权 */
    async handleGrant(row = {}) {
      const { data } = await listRoleUsers({ roleId: row.id })
      const res = await roleUsersAndGroups({ roleId: row.id })
      this.$refs.usergrantDialog.init(row, { list: data.userRoleResDO, listGroup: res.data.roleGroupsRespVoList })
      this.currow = row
    },
    /** 保存对象授权*/
    emitplayer(obj) {
      if (!this.currow) {
        return this.$message.error('请选择角色')
      }
      const params1 = {
        roleId: this.currow.id,
        orgUserReqs: obj.list
      }
      assignRoleUsers(params1).then(res => {
        // this.$message.success('授权成功')
      })
      let arr = []
      if (obj.listGroup.length > 0) {
        obj.listGroup.map(mat => {
          arr.push(mat.id)
        })
      }
      const params2 = {
        roleId: this.currow.id,
        groupId: arr
      }
      updateRoleUsersAndGroups(params2).then(res => {
        this.$message.success('保存成功')
        this.getList();
      })
    },
    // 角色状态修改
    handleStatusChange(row) {
      // 此时，row 已经变成目标状态了，所以可以直接提交请求和提示
      let text = row.status === CommonStatusEnum.ENABLE ? "启用" : "停用";
      this.$modal.confirm('确认要"' + text + '""' + row.name + '"角色吗?').then(function () {
        return changeRoleStatus(row.id, row.status);
      }).then(() => {
        this.$modal.msgSuccess(text + "成功");
      }).catch(function () {
        // 异常时，需要将 row.status 状态重置回之前的
        row.status = row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE
          : CommonStatusEnum.ENABLE;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 取消按钮（数据权限）
    cancelDataScope() {
      this.openDataScope = false;
      this.reset();
    },
    // 取消按钮（菜单权限）
    cancelMenu() {
      this.openMenu = false;
      this.reset();
    },
    // 表单重置
    reset() {
      if (this.$refs.menu !== undefined) {
        this.$refs.menu.setCheckedKeys([]);
      }
      this.menuExpand = false;
      this.menuNodeAll = false;
      this.deptExpand = true;
      this.deptNodeAll = false;
      this.form = {
        id: undefined,
        name: undefined,
        code: undefined,
        sort: 0,
        deptIds: [],
        menuIds: [],
        dataScope: undefined,
        deptCheckStrictly: false,
        menuCheckStrictly: true,
        remark: undefined
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNo = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 树权限（展开/折叠）
    handleCheckedTreeExpand(value, type) {
      if (type === 'menu') {
        let treeList = this.menuOptions;
        for (let i = 0; i < treeList.length; i++) {
          this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
        }
      } else if (type === 'dept') {
        let treeList = this.deptOptions;
        for (let i = 0; i < treeList.length; i++) {
          this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
        }
      }
    },
    // 树权限（全选/全不选）
    handleCheckedTreeNodeAll(value, type) {
      if (type === 'menu') {
        this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
      } else if (type === 'dept') {
        // this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
        this.$refs.dept.setCheckedNodes(value ? this.depts : []);
      }
    },
    // 树权限（父子联动）
    handleCheckedTreeConnect(value, type) {
      if (type === 'menu') {
        this.form.menuCheckStrictly = value;
      } else if (type === 'dept') {
        this.form.deptCheckStrictly = !value;
      }
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加角色";
    },
    /**状态更改 */
    handleEditStatus(row, status, text) {
      let { id } = row;
      this.$modal.confirm('确认要"' + text + '""' + row.name + '"角色吗?').then(function () {
        return updateRoleStatus({ id, status });
      }).then(() => {
        this.$modal.msgSuccess(text + "成功");
        this.getList()
      }).catch(function () {
        this.$modal.msgSuccess(text + "失败");
      });
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const { id } = row
      getRole({ id }).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改角色";
      });
    },
    /** 分配菜单权限操作 */
    handleMenu(row) {
      this.reset();
      const id = row.id
      // 处理了 form 的角色 name 和 code 的展示
      this.form.id = id;
      this.form.name = row.name;
      this.form.code = row.code;
      // 打开弹窗
      this.openMenu = true;
      // 获得菜单列表
      listSimpleMenus().then(response => {
        // 处理 menuOptions 参数
        this.menuOptions = [];
        this.menuOptions.push(...this.handleTree(response.data, "id"));
        // 获取角色拥有的菜单权限
        listRoleMenus(id).then(response => {
          // 设置为严格，避免设置父节点自动选中子节点，解决半选中问题
          this.form.menuCheckStrictly = true
          // 设置选中
          this.$refs.menu.setCheckedKeys(response.data);
          // 设置为非严格，继续使用半选中
          this.form.menuCheckStrictly = false
        })
      });

    },
    /** 分配数据权限操作 */
    handleDataScope(row) {
      console.log(row);
      this.$router.push({ name: 'FunctionMange', query: { id: row.id } })
      // this.reset();
      // // 处理了 form 的角色 name 和 code 的展示
      // this.form.id = row.id;
      // this.form.name = row.name;
      // this.form.code = row.code;
      // // 打开弹窗
      // this.openDataScope = true;
      // // 获得部门列表
      // listSimpleDepts().then(response => {
      //   // 处理 deptOptions 参数
      //   this.deptOptions = [];
      //   this.deptOptions.push(...this.handleTree(response.data, "id"));
      //   this.depts = response.data;
      //   // this.deptIds = response.data.map(x => x.id);
      //   // 获得角色拥有的数据权限
      //   getRole(row.id).then(response => {
      //     this.form.dataScope = response.data.dataScope;
      //     this.$refs.dept.setCheckedKeys(response.data.dataScopeDeptIds, false);
      //   });
      // });
    },
    /** 提交按钮 */
    submitForm: function () {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id !== undefined) {
            updateRole(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            createRole(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 提交按钮（数据权限） */
    submitDataScope: function () {
      if (this.form.id !== undefined) {
        assignRoleDataScope({
          roleId: this.form.id,
          dataScope: this.form.dataScope,
          dataScopeDeptIds: this.form.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM ? [] :
            this.$refs.dept.getCheckedKeys()
        }).then(response => {
          this.$modal.msgSuccess("修改成功");
          this.openDataScope = false;
          this.getList();
        });
      }
    },
    /** 提交按钮（菜单权限） */
    submitMenu: function () {
      if (this.form.id !== undefined) {
        assignRoleMenu({
          roleId: this.form.id,
          menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()]
        }).then(response => {
          this.$modal.msgSuccess("修改成功");
          this.openMenu = false;
          this.getList();
        });
      }
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const id = row.id;
      this.$modal.confirm('是否确认删除此角色吗?').then(function () {
        return delRole({ id });
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$modal.confirm('是否确认导出所有角色数据项?').then(function () {
        this.exportLoading = true;
        return exportRole(queryParams);
      }).then(response => {
        this.$download.excel(response, '角色数据.xls');
        this.exportLoading = false;
      }).catch(() => { });
    },
    verifyName(rule, val, callback) {
      if (val) {
        if (val.length > 25) callback(Error('用户组名称支持输入1~25个字'));
        let re = /^[\u4E00-\u9FA5A-Za-z]+$/;
        if (!re.test(val)) callback(Error('支持中文、英文（区分大小写）'));
        else callback();
      } else {
        callback();
      }
    },
  }
};
</script>
